
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0,viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
<meta name="description" content="实现故障恢复自动化：详解Redis哨兵技术。中国Redis用户组（CRUG）之网络文章大全">

        
        <title>
 实现故障恢复自动化：详解Redis哨兵技术
</title>
        
<style>.radius_avatar{display:inline-block;background-color:#fff;padding:3px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;overflow:hidden;vertical-align:middle}.radius_avatar img{display:block;width:100%;height:100%;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background-color:#eee}.rich_media_inner{word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.rich_media_area_primary{padding:20px 16px 12px;background-color:#fafafa}.rich_media_area_primary.voice{padding-top:66px}.rich_media_area_primary .weui-loadmore_line .weui-loadmore__tips{color:rgba(0,0,0,0.3);background-color:#fafafa}.rich_media_area_extra{padding:0 16px 24px}.rich_media_extra{padding-top:30px}.mpda_bottom_container .rich_media_extra{padding-top:24px}html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.6}body{-webkit-touch-callout:none;font-family:-apple-system-font,BlinkMacSystemFont,"Helvetica Neue","PingFang SC","Hiragino Sans GB","Microsoft YaHei UI","Microsoft YaHei",Arial,sans-serif;color:#333;background-color:#f2f2f2;letter-spacing:.034em}h1,h2,h3,h4,h5,h6{font-weight:400;font-size:16px}*{margin:0;padding:0}a{color:#576b95;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rich_media_title{font-size:22px;line-height:1.4;margin-bottom:14px}@supports(-webkit-overflow-scrolling:touch){.rich_media_title{font-weight:700}}.rich_media_meta_list{margin-bottom:22px;line-height:20px;font-size:0;word-wrap:break-word;word-break:break-all}.rich_media_meta_list em{font-style:normal}.rich_media_meta{display:inline-block;vertical-align:middle;margin:0 10px 10px 0;font-size:15px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.rich_media_meta.icon_appmsg_tag{margin-right:4px}.rich_media_meta.meta_tag_text{margin-right:0}.rich_media_meta_primary{display:block;margin-bottom:10px;font-size:15px}.meta_original_tag{padding:0 .5em;font-size:12px;line-height:1.4;background-color:#f2f2f2;color:#888}.meta_enterprise_tag img{width:30px;height:30px!important;display:block;position:relative;margin-top:-3px;border:0}.rich_media_meta_link{color:#576b95}.rich_media_meta_text{color:rgba(0,0,0,0.3)}.rich_media_meta_text.rich_media_meta_split{padding-left:10px}.rich_media_meta_text.rich_media_meta_split:before{position:absolute;top:50%;left:0;margin-top:-6px;content:' ';display:block;border-left:1px solid #888;width:200%;height:130%;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-webkit-transform:scale(0.5);transform:scale(0.5);-webkit-transform-origin:0 0;transform-origin:0 0}.rich_media_meta_text.article_modify_tag{position:relative}.rich_media_meta_nickname{position:relative}.rich_media_thumb_wrp{margin-bottom:6px}.rich_media_thumb_wrp .original_img_wrp{display:block}.rich_media_thumb{display:block;width:100%}.rich_media_content{overflow:hidden;color:#333;font-size:17px;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;text-align:justify}.rich_media_content *{max-width:100%!important;box-sizing:border-box!important;-webkit-box-sizing:border-box!important;word-wrap:break-word!important}.rich_media_content p{clear:both;min-height:1em}.rich_media_content em{font-style:italic}.rich_media_content fieldset{min-width:0}.rich_media_content .list-paddingleft-2{padding-left:2.2em}.rich_media_content .list-paddingleft-2 .list-paddingleft-2{padding-left:30px}.rich_media_content blockquote{margin:0;padding-left:10px;border-left:3px solid #dbdbdb}.weui-mask{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0;background:rgba(0,0,0,0.6)}.weui-dialog{position:fixed;z-index:5000;width:80%;max-width:300px;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background-color:#fff;text-align:center;border-radius:3px;overflow:hidden}.weui-dialog__hd{padding:1.3em 1.6em .5em}.weui-dialog__title{font-weight:400;font-size:18px}.weui-dialog__bd{padding:0 1.6em .8em;min-height:40px;font-size:15px;line-height:1.3;word-wrap:break-word;word-break:break-all;color:#999}.weui-dialog__bd:first-child{padding:2.7em 20px 1.7em;color:#353535}.weui-dialog__ft{position:relative;line-height:48px;font-size:18px;display:-webkit-box;display:-webkit-flex;display:flex}.weui-dialog__ft:after{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.weui-dialog__btn{display:block;-webkit-box-flex:1;-webkit-flex:1;flex:1;color:#3cc51f;text-decoration:none;-webkit-tap-highlight-color:rgba(0,0,0,0);position:relative}.weui-dialog__btn:active{background-color:#eee}.weui-dialog__btn:after{content:" ";position:absolute;left:0;top:0;width:1px;bottom:0;border-left:1px solid #d5d5d6;color:#d5d5d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5)}.weui-dialog__btn:first-child:after{display:none}.weui-dialog__btn_default{color:#353535}.weui-dialog__btn_primary{color:#0bb20c}img{height:auto!important}@media only screen and (device-width:375px) and (device-height:812px) and (-webkit-device-pixel-ratio:3) and (orientation:portrait){.rich_media_area_extra{padding-bottom:34px}}@media only screen and (device-width:375px) and (device-height:812px) and (-webkit-device-pixel-ratio:3) and (orientation:landscape){.rich_media_area_primary{padding:20px 60px 15px 60px}.rich_media_area_extra{padding:0 60px 21px 60px}}@media screen and (min-width:1024px){.rich_media_area_primary_inner,.rich_media_area_extra_inner{max-width:677px;margin-left:auto;margin-right:auto}.rich_media_area_primary{padding-top:32px}}.appmsg_share_notice{font-size:16px;color:#888;position:relative;padding:1.25em 0;margin-bottom:1.75em}.appmsg_share_notice:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #dfdfdf;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.appmsg_share_notice:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #dfdfdf;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.appmsg_share_notice_hd{font-weight:700;padding-bottom:.2em}.cell{padding:.8em 0;display:block;position:relative}.cell_hd,.cell_bd,.cell_ft{display:table-cell;vertical-align:middle;word-wrap:break-word;word-break:break-all;white-space:nowrap}.cell_primary{width:2000px;white-space:normal}.flex_cell{padding:10px 0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.flex_cell_primary{width:100%;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;box-flex:1;flex:1}.original_tool_area{display:block;padding:.75em 1em 0;-webkit-tap-highlight-color:rgba(0,0,0,0);color:#333;border:1px solid #eaeaea;margin:20px 0}.original_tool_area .tips_global{position:relative;padding-bottom:.5em;font-size:15px}.original_tool_area .tips_global:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #dbdbdb;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.original_tool_area .radius_avatar{width:27px;height:27px;padding:0;margin-right:.5em}.original_tool_area .radius_avatar img{height:100%!important}.original_tool_area .flex_cell_bd{width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.original_tool_area .flex_cell_ft{font-size:14px;color:#888;padding-left:1em;white-space:nowrap}.original_tool_area .icon_access:after{content:" ";display:inline-block;height:8px;width:8px;border-width:1px 1px 0 0;border-color:#cbcad0;border-style:solid;transform:matrix(0.71,0.71,-0.71,0.71,0,0);-ms-transform:matrix(0.71,0.71,-0.71,0.71,0,0);-webkit-transform:matrix(0.71,0.71,-0.71,0.71,0,0);position:relative;top:-2px;top:-1px}.rich_media_global_msg{position:fixed;top:0;left:0;right:0;padding:.85em 35px .85em 15px;z-index:2;background-color:#c6e0f8;color:#888;font-size:12px}.rich_media_global_msg .icon_closed{position:absolute;right:15px;top:50%;margin-top:-5px;line-height:300px;overflow:hidden;-webkit-tap-highlight-color:rgba(0,0,0,0);background:transparent url(//res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/icon/appmsg/icon_appmsg_msg_closed_sprite.2x2eb52b.png) no-repeat 0 0;width:11px;height:11px;vertical-align:middle;display:inline-block;-webkit-background-size:100% auto;background-size:100% auto}.rich_media_global_msg .icon_closed:active{background-position:0 -17px}.rich_media_global_msg.voice{color:#1aad19;background-color:#e8f6e8;padding-left:43.3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rich_media_global_msg.voice .ic_voice{position:absolute;top:50%;margin-top:-10px;left:15px;display:inline-block;width:13.3px;height:18.3px;background:url() no-repeat center;background-size:contain}.rich_media_global_msg.voice .icon_more{position:absolute;right:15px;top:50%;margin-top:-6.5px;width:8px;height:13px;background:url() no-repeat center;background-size:contain}.preview_appmsg .rich_media_title{margin-top:2.3em}@media screen and (min-width:1024px){.rich_media_global_msg{position:relative;margin-bottom:32px}.preview_appmsg .rich_media_title.rich_media_title{margin-top:0}}.pages_reset{color:#333;line-height:1.6;font-size:16px;font-weight:400;font-style:normal;text-indent:0;letter-spacing:normal;text-align:left;text-decoration:none;white-space:normal}.weapp_element,.weapp_display_element,.mp-miniprogram{display:block;margin:1em 0}.share_audio_context{margin:16px 0}.weapp_text_link{font-size:17px}.weapp_text_link:before{content:'';display:inline-block;line-height:1;background-size:contain;background-repeat:no-repeat;background-image:url('');vertical-align:middle;font-size:11px;color:#888;margin-right:6px;margin-top:-3px;background-position:center;height:20px;width:20px}.flex_context{display:-webkit-box;display:-webkit-flex;display:flex;-webkit-box-align:center;-webkit-align-items:center;align-items:center}.flex_bd{-webkit-box-flex:1;-webkit-flex:1;flex:1;word-wrap:break-word;word-break:break-all}.original_page{background-color:#fff;font-size:16px}.account_info{padding:0 0 20px}.account_info .flex_bd{padding-left:.85em}.radius_avatar.account_avatar{width:40px;height:40px;padding:0}.account_nickname{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-height:1.2;color:#576b95;font-size:14px}.account_nickname_inner{font-weight:400;vertical-align:top}.account_desc{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;color:#b2b2b2;font-size:13px;line-height:1.2;padding-top:.3em}.account_desc_inner{display:inline;vertical-align:top}.share_notice{margin-bottom:20px;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.share_media{padding-bottom:18px}.original_panel{padding:20px;background-color:#fcfcfc;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;overflow:hidden;position:relative}.original_panel:after{content:" ";border:1px solid #d8d8d8;border-radius:4px;-moz-border-radius:4px;-webkit-border-radius:4px;position:absolute;top:0;left:0;width:200%;height:200%;-webkit-transform:scale(0.5);transform:scale(0.5);-webkit-transform-origin:0 0;transform-origin:0 0;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.original_panel .original_account{margin-bottom:18px;position:relative;z-index:1}.original_panel .original_account_avatar{width:28px;height:28px;padding:0}.original_panel .original_account_nickname{padding-left:.85em;font-size:15px;color:#576b95}.original_panel_title{font-size:23px;color:#000;margin:0 0 16px}.original_panel_content{color:#333}.original_panel_tool{padding-top:20px;position:relative;z-index:1}.original_cell_nickname{display:inline-block;vertical-align:middle;font-weight:400;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;max-width:8em;color:#000}.original_tool_area{padding:1.17em 0;border-width:0;position:relative}.original_tool_area:before{content:" ";position:absolute;left:0;top:0;right:0;height:1px;border-top:1px solid #dfdfdf;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.original_tool_area:after{content:" ";position:absolute;left:0;bottom:0;right:0;height:1px;border-bottom:1px solid #dfdfdf;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.original_tool_area .radius_avatar{width:20px;height:20px;margin-right:.2em}.original_tool_area .flex_cell{padding:0;font-size:14px}.original_tool_area .icon_access:after{margin-right:4px;top:0}.preview_appmsg .rich_media_title{margin-top:1.5em}.preview_appmsg .account_info{padding-top:3em}.original_page{background-color:transparent}.account_info{-webkit-tap-highlight-color:rgba(0,0,0,0);outline:0;padding-bottom:20px;font-size:14px}.account_info.appmsg_account_info{padding-bottom:32px}.account_info .radius_avatar img{background-color:transparent}.share_notice{font-size:16px;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.original_panel{background-color:#fafafa}.original_panel:after{border-color:#e6e6e6}.original_panel .original_account_avatar{width:30px;height:30px}.original_panel_tool{font-size:14px}.original_panel_tool a{color:#576b95}.original_panel_content{font-size:17px}.share_media{padding-bottom:30px}.icon_appmsg_tag{display:inline-block;vertical-align:middle;padding:0 .5em;font-size:12px;line-height:1.5;background-color:#c3c3c3;color:#fff;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;max-width:70%}.icon_appmsg_tag.primary{color:#3bb638;padding:4px .78em;background-color:rgba(9,187,7,0.08);font-size:12px;border-top-left-radius:.95em 50%;-moz-border-radius-topleft:.95em 50%;-webkit-border-top-left-radius:.95em 50%;border-top-right-radius:.95em 50%;-moz-border-radius-topright:.95em 50%;-webkit-border-top-right-radius:.95em 50%;border-bottom-left-radius:.95em 50%;-moz-border-radius-bottomleft:.95em 50%;-webkit-border-bottom-left-radius:.95em 50%;border-bottom-right-radius:.95em 50%;-moz-border-radius-bottomright:.95em 50%;-webkit-border-bottom-right-radius:.95em 50%}.icon_appmsg_tag.default{border:1px solid rgba(0,0,0,0.1);color:rgba(0,0,0,0.3);background-color:transparent;padding:0 .54em;font-size:15px;line-height:1.3;border-top-left-radius:.67em 50%;-moz-border-radius-topleft:.67em 50%;-webkit-border-top-left-radius:.67em 50%;border-top-right-radius:.67em 50%;-moz-border-radius-topright:.67em 50%;-webkit-border-top-right-radius:.67em 50%;border-bottom-left-radius:.67em 50%;-moz-border-radius-bottomleft:.67em 50%;-webkit-border-bottom-left-radius:.67em 50%;border-bottom-right-radius:.67em 50%;-moz-border-radius-bottomright:.67em 50%;-webkit-border-bottom-right-radius:.67em 50%}.rich_media_meta_list .icon_appmsg_tag.default{margin-top:-1px}.icon_appmsg_tag.title_tag{background-color:#d04b4e}.icon_global_tag_wrp{text-align:right;padding-bottom:12px}.icon_global_tag{background-color:rgba(118,118,118,0.16);color:rgba(0,0,0,0.41);line-height:2.2;border-top-left-radius:1em 50%;-moz-border-radius-topleft:1em 50%;-webkit-border-top-left-radius:1em 50%;border-bottom-left-radius:1em 50%;-moz-border-radius-bottomleft:1em 50%;-webkit-border-bottom-left-radius:1em 50%;padding:0 1.8em 0 1.34em;font-size:12px;margin-right:-24px;display:inline-block;vertical-align:top}.global_plain_btn{display:inline-block;vertical-align:middle;padding:0 1em;line-height:2;font-size:14px;-webkit-tap-highlight-color:rgba(0,0,0,0);border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px}.global_plain_btn.primary{color:#1aad19;border:1px solid currentColor}.global_plain_btn.primary:active{color:rgba(26,173,25,0.6)}.wx_video_context{color:#fefefe;position:relative;background-color:#000}.wx_video_thumb,.wx_video_thumb_primary{position:absolute;left:0;width:100%;height:100%!important;top:0}.wx_video_thumb_primary{-webkit-background-size:cover;background-size:cover;background-position:50% 50%;background-repeat:no-repeat}.wx_video_play_btn{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);margin-top:-2px;font-size:0;border-width:0;background-color:transparent;padding:0;outline:0;z-index:2}.wx_video_play_btn:before{content:" ";display:inline-block;width:0;height:0;border-width:14px 0 14px 25px;border-color:transparent transparent transparent #fff;border-style:dotted dotted dotted solid}.wx_video_mask{position:absolute;top:0;left:0;right:0;bottom:0;z-index:1;background-color:rgba(0,0,0,0.5)}.place_audio_area{min-height:100px;background-color:#fdfdfd;display:block;margin:16px 0}.place_music_area{min-height:68px;background-color:#fdfdfd;display:block;margin:17px 0 16px}.rich_media_empty_extra{background-color:#fafafa}.appmsg_skin_default.rich_media_empty_extra{background-color:#fff}.appmsg_skin_default .rich_media_area_primary{background-color:#fff}.appmsg_skin_default .rich_media_area_primary .weui-loadmore_line .weui-loadmore__tips{background-color:#fff}.appmsg_style_default .rich_media_tool{padding-top:15px}.rich_media_title_ios{font-weight:700}</style>
<style>
        </style>
<!--[if lt IE 9]>
<link rel="stylesheet" type="text/css" href="//res.wx.qq.com/mmbizwap/zh_CN/htmledition/style/page/appmsg_new/pc3ec991.css">
<![endif]-->

    </head>
    <body id="activity-detail" class="zh_CN mm_appmsg  appmsg_skin_default appmsg_style_default">
        
<div id="js_article" class="rich_media">
    
    <div id="js_top_ad_area" class="top_banner"></div>
    
    <div class="rich_media_inner">

        
        
        <div id="page-content" class="rich_media_area_primary">
          <div class="rich_media_area_primary_inner">
                                    
                        

            <div id="img-content">

                
                <h2 class="rich_media_title" id="activity-name">
                    
                    
                    实现故障恢复自动化：详解Redis哨兵技术

                                                                                </h2>
                
                
                
                
                
                                                
                                                                
                                
                
                <div class="rich_media_content " id="js_content">
                    

                    

                    
                    
                    <section class="xmteditor" style="display:none;" data-tools="新媒体管家" data-label="powered by xmt.cn"></section>
					
<p style="text-align: center;"><br  /></p><section data-role="outer" label="Powered by 135editor.com" style="font-size: 16px;font-family: 微软雅黑;"><section data-role="paragraph" class="_135editor" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde">
					
<p style="line-height: 1.75em;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在前面分享的</span><a href="http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&amp;mid=2650770433&amp;idx=1&amp;sn=6bca1f9be39f3cb7b3cb331faad971ed&amp;chksm=f3f93994c48eb0822be00fd0708ac90c94f2557d38949613c2661b72a704175e7660269d3dff&amp;scene=21#wechat_redirect" target="_blank" style="text-decoration: underline;font-family: 微软雅黑, sans-serif;font-size: 15px;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">《读完这篇文章，就基本搞定了Redis主从复制》</span></a><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">中我们曾提到，Redis主从复制的作用有数据热备、负载均衡、故障恢复等；但主从复制存在的一个问题是故障恢复无法自动化。本文将要介绍的哨兵，它基于Redis主从复制，主要作用便是解决主节点故障恢复的自动化问题，进一步提高系统的高可用性。</span><br  /></p>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">注：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">本文内容基于Redis 3.0版本。</span></p>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
					
<p style="font-size: 20px;line-height: normal;letter-spacing: 0.5px;"><span style="font-size: 16px;"><strong>一、作用和架构</strong></span></p></section></section></section></section>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">1.作用</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在介绍哨兵之前，首先从宏观角度回顾一下Redis实现高可用相关的技术。它们包括：持久化、复制、哨兵和集群，其主要作用和解决的问题是：</span></p>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">持久化：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">持久化是最简单的高可用方法（有时甚至不被归为高可用的手段），主要作用是数据备份，即将数据存储在硬盘，保证数据不会因进程退出而丢失。</span></p></li><li>
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">复制：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">复制是高可用Redis的基础，哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份，以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化；写操作无法负载均衡；存储能力受到单机的限制。</span></p></li><li>
					
					
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在复制的基础上，哨兵实现了自动化的故障恢复。缺陷是写操作无法负载均衡；存储能力受到单机的限制。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">集群：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">通过集群，Redis解决了写操作无法负载均衡，以及存储能力受到单机限制的问题，实现了较为完善的高可用方案。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;"><br  /></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">详细内容可回顾：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;"><br  /></span></p><ul class=" list-paddingleft-2" style="list-style-type: disc;"><li>
<p><a href="http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&amp;mid=2650769300&amp;idx=1&amp;sn=49a11efa1a6ee605fceaddf240a55c40&amp;chksm=f3f93201c48ebb175fa76053d95e315b621485b0e65e42d8b41fe91b8f859c9278f3adec7ca9&amp;scene=21#wechat_redirect" target="_blank" style="text-decoration: underline;font-size: 14px;color: rgb(136, 136, 136);"><span style="font-size: 14px;color: rgb(136, 136, 136);">Redis高可用详解：持久化技术及方案选择</span></a><br  /></p></li><li>
<p><a href="http://mp.weixin.qq.com/s?__biz=MzI4NTA1MDEwNg==&amp;mid=2650770433&amp;idx=1&amp;sn=6bca1f9be39f3cb7b3cb331faad971ed&amp;chksm=f3f93994c48eb0822be00fd0708ac90c94f2557d38949613c2661b72a704175e7660269d3dff&amp;scene=21#wechat_redirect" target="_blank" style="text-decoration: underline;font-size: 14px;color: rgb(136, 136, 136);"><span style="font-size: 14px;color: rgb(136, 136, 136);">读完这篇文章，就基本搞定了Redis主从复制</span></a><br  /></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">下面说回哨兵。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Redis Sentinel，即Redis哨兵，在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。下面是Redis官方文档对于哨兵功能的描述：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">监控（Monitoring）：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵会不断地检查主节点和从节点是否运作正常。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">自动故障转移（Automatic Failover）：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">当主节点不能正常工作时，哨兵会开始自动故障转移操作，它会将失效主节点的其中一个从节点升级为新的主节点，并让其他从节点改为复制新的主节点。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">配置提供者（Configuration Provider）：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">客户端在初始化时，通过连接哨兵来获得当前Redis服务的主节点地址。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">通知（Notification）：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">哨兵可以将故障转移的结果发送给客户端。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">其中，监控和自动故障转移功能，使得哨兵可以及时发现主节点故障并完成转移；而配置提供者和通知功能，则需要在与客户端的交互中才能体现。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">这里对“客户端”一词在文章中的用法做一个说明：在前面的文章中，只要通过API访问Redis服务器，都会称作客户端，包括Redis-cli、Java客户端Jedis等。为了便于区分说明，本文中的客户端并不包括Redis-cli，而是比Redis-cli更加复杂：Redis-cli使用的是Redis提供的底层接口，而客户端则对这些接口、功能进行了封装，以便充分利用哨兵的配置提供者和通知功能。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">2.架构</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">典型的哨兵架构图如下所示：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.7672634271099744" data-s="300,640" src="/images/articles/20181020001_001.webp" data-type="png" data-w="391" style="width:65%;height:auto;"></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><br  /></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">它由两部分组成：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵系统由一个或多个哨兵节点组成，哨兵节点是特殊的Redis节点，不存储数据。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">数据节点：</span></strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">主节点和从节点都是数据节点。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
<p style="font-size: 20px;letter-spacing: 0.5px;line-height: normal;"><strong><span style="font-size: 16px;">二、部署</span></strong></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">这一部分将部署一个简单的哨兵系统，包含1个主节点、2个从节点和3个哨兵节点。方便起见，所有这些节点都部署在一台机器上（局域网IP：192.168.92.128），使用端口号区分；且节点的配置尽可能简化。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">1.部署主从节点</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵系统中的主从节点，与普通的主从节点配置是一样的，并不需要做任何额外配置。下面分别是主节点（port=6379）和2个从节点（port=6380/6381）的配置文件，配置都比较简单，不再详述：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush"><span style="font-size: 10px;caret-color: red;">#redis-6379.conf</span>
<p><span style="font-size: 10px;">port 6379</span></p>
<p><span style="font-size: 10px;">daemonize yes</span></p>
<p><span style="font-size: 10px;">logfile "6379.log"</span></p>
<p><span style="font-size: 10px;">dbfilename "dump-6379.rdb"</span></p>
<p><br  /></p>
<p><span style="font-size: 10px;">#redis-6380.conf</span></p>
<p><span style="font-size: 10px;">port 6380</span></p>
<p><span style="font-size: 10px;">daemonize yes</span></p>
<p><span style="font-size: 10px;">logfile "6380.log"</span></p>
<p><span style="font-size: 10px;">dbfilename "dump-6380.rdb"</span></p>
<p><span style="font-size: 10px;">slaveof 192.168.92.128 6379</span></p>
<p><br  /></p>
<p><span style="font-size: 10px;">#redis-6381.conf</span></p>
<p><span style="font-size: 10px;">port 6381</span></p>
<p><span style="font-size: 10px;">daemonize yes</span></p>
<p><span style="font-size: 10px;">logfile "6381.log"</span></p>
<p><span style="font-size: 10px;">dbfilename "dump-6381.rdb"</span></p>
<p><span style="font-size: 10px;">slaveof 192.168.92.128 6379</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置完成后，依次启动主节点和从节点：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush">
<p><span style="font-size: 10px;">redis-server redis-6379.conf</span></p>
<p><span style="font-size: 10px;">redis-server redis-6380.conf</span></p>
<p><span style="font-size: 10px;">redis-server redis-6381.conf</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">节点启动后，连接主节点查看主从状态是否正常，如下图所示：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.3194945848375451" data-s="300,640" src="/images/articles/20181020001_002.webp" data-type="png" data-w="554" style="width:85%;height:auto;"></p>
<p style="text-align: center;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">2.部署哨兵节点</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点本质上是特殊的Redis节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">3个哨兵节点的配置几乎是完全一样的，主要区别在于端口号的不同（26379 / 26380 / 263 81），下面以26379节点为例介绍节点的配置和启动方式；配置部分尽量简化，更多配置会在后面介绍：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush">
<p><span style="font-size: 10px;">#sentinel-26379.conf</span></p>
<p><span style="font-size: 10px;">port 26379</span></p>
<p><span style="font-size: 10px;">daemonize yes</span></p>
<p><span style="font-size: 10px;">logfile&nbsp;"26379.log"</span></p>
<p><span style="font-size: 10px;">sentinel monitor mymaster 192.168.92.128 &nbsp; 6379 2</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">其中，sentinel monitor mymaster 192.168. 92.128 6379 2配置的含义是：该哨兵节点监控192.168.92.128:6379这个主节点，该主节点的名称是mymaster，最后的2的含义与主节点的故障判定有关：至少需要2个哨兵节点同意，才能判定主节点故障并进行故障转移。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点的启动有两种方式，二者作用是完全相同的：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush">
<p><span style="font-size: 10px;">redis-sentinel sentinel-26379.conf</span></p>
<p><span style="font-size: 10px;">redis-server &nbsp; sentinel-26379.conf&nbsp;--sentinel</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">按照上述方式配置和启动之后，整个哨兵系统就启动完毕了。可以通过Redis-cli连接哨兵节点进行验证，如下图所示：可以看出26379哨兵节点已经在监控mymaster主节点（即192.168.92.128:6379），并发现了其2个从节点和另外2个哨兵节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.18231046931407943" data-s="300,640" src="/images/articles/20181020001_003.webp" data-type="png" data-w="554" style="width:100%;height:auto;"></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><br  /></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">此时如果查看哨兵节点的配置文件，会发现一些变化，以26379为例：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.30505415162454874" data-s="300,640" src="/images/articles/20181020001_004.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">其中，dir只是显式声明了数据和日志所在的目录（在哨兵语境下只有日志）；known-slave和known-sentinel显示哨兵已经发现了从节点和其他哨兵；带有epoch的参数与配置纪元有关（配置纪元是一个从0开始的计数器，每进行一次领导者哨兵选举，都会+1；领导者哨兵选举是故障转移阶段的一个操作，在后文原理部分会介绍）。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">3.演示故障转移</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵的4个作用中，配置提供者和通知需要客户端的配合，本文将在下一章介绍客户端访问哨兵系统的方法时详细介绍。这一小节将演示当主节点发生故障时，哨兵的监控和自动故障转移功能。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Step1：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">首先，使用kill命令杀掉主节点：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.09566787003610108" data-s="300,640" src="/images/articles/20181020001_005.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Step2：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">如果此时立即在哨兵节点中使用info Sentinel命令查看，会发现主节点还没有切换过来，因为哨兵发现主节点故障并转移，需要一段时间。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.17328519855595667" data-s="300,640" src="/images/articles/20181020001_006.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Step3：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">一段时间以后，再次在哨兵节点中执行info Sentinel查看，发现主节点已经切换成6380节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.1624548736462094" data-s="300,640" src="/images/articles/20181020001_007.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">但是同时可以发现，哨兵节点认为新的主节点仍然有2个从节点，这是因为哨兵在将6380切换成主节点的同时，将6379节点置为其从节点；虽然6379从节点已经挂掉，但是由于哨兵并不会对从节点进行客观下线（其含义将在原理部分介绍），因此认为该从节点一直存在。当6379节点重新启动后，会自动变成6380节点的从节点。下面验证一下。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Step4：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">重启6379节点，可以看到6379节点成为了6380节点的从节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.30144404332129965" data-s="300,640" src="/images/articles/20181020001_008.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Step5：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在故障转移阶段，哨兵和主从节点的配置文件都会被改写。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">对于主从节点，主要是slaveof配置的变化：新的主节点没有了slaveof配置，其从节点则slaveof新的主节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">对于哨兵节点，除了主从节点信息的变化，纪元(epoch)也会变化，下图中可以看到纪元相关的参数都+1了。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.30144404332129965" data-s="300,640" src="/images/articles/20181020001_009.webp" data-type="png" data-w="554" style=""></p>
<p style="text-align: center;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">4.总结</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵系统的搭建过程，有几点需要注意：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵系统中的主从节点，与普通的主从节点并没有什么区别，故障发现和转移是由哨兵来控制和完成的。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">哨兵节点本质上是Redis节点。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">每个哨兵节点，只需要配置监控主节点，便可以自动发现其他的哨兵节点和从节点。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">在哨兵节点启动和故障转移阶段，各个节点的配置文件会被重写（Config Rewrite）。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">本章的例子中，一个哨兵只监控了一个主节点；实际上，一个哨兵可以监控多个主节点，通过配置多条sentinel monitor即可实现。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
<p style="font-size: 20px;letter-spacing: 0.5px;line-height: normal;"><span style="font-size: 16px;"><strong>三、客户端访问哨兵系统</strong></span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">上一小节演示了哨兵的两大作用：监控和自动故障转移，本小节则结合客户端演示哨兵的另外两个作用：配置提供者和通知。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">1.代码示例</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在介绍客户端的原理之前，先以Java客户端Jedis为例，演示一下使用方法：下面代码可以连接我们刚刚搭建的哨兵系统，并进行各种读写操作：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush">
<p><span style="font-size: 10px;">public&nbsp;static&nbsp;void&nbsp;testSentinel()&nbsp;throws&nbsp;Exception &nbsp; {</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String &nbsp; masterName =&nbsp;"mymaster";</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;String&gt; &nbsp; sentinels =&nbsp;new&nbsp;HashSet&lt;&gt;();</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sentinels.add("192.168.92.128:26379");</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sentinels.add("192.168.92.128:26380");</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sentinels.add("192.168.92.128:26381");</span></p>
<p><br  /></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JedisSentinelPool &nbsp; pool =&nbsp;new&nbsp;JedisSentinelPool(masterName, sentinels);&nbsp;//<span style="font-family: 宋体;">初始化过程做了很多工作</span></span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Jedis &nbsp; jedis = pool.getResource();</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jedis.set("key1",&nbsp;"value1");</span></p>
<p><span style="font-size: 10px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pool.close();</span></p>
<p><span style="font-size: 10px;">}</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;letter-spacing: 0.5px;text-align: justify;font-size: 12px;color: rgb(136, 136, 136);">（注：代码中只演示如何连接哨兵，异常处理、资源关闭等未考虑）</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">2.客户端原理</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">Jedis客户端对哨兵提供了很好的支持。如上述代码所示，我们只需要向Jedis提供哨兵节点集合和masterName，构造Jedis SentinelPool对象；然后便可以像使用普通Redis连接池一样来使用了：通过pool.getResource()获取连接，执行具体的命令。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在整个过程中，我们的代码不需要显式的指定主节点的地址，就可以连接到主节点；代码中对故障转移没有任何体现，就可以在哨兵完成故障转移后自动的切换主节点。之所以可以做到这一点，是因为在JedisSentinelPool的构造器中，进行了相关的工作，主要包括以下两点：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">遍历哨兵节点，获取主节点信息：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">遍历哨兵节点，通过其中一个哨兵节点+masterName获得主节点的信息；该功能是通过调用哨兵节点的sentinel get-master-addr-by-name命令实现，该命令示例如下：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.13382899628252787" data-s="300,640" src="/images/articles/20181020001_010.webp" data-type="png" data-w="538" style="width:85%;height:auto;"></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><br  /></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">一旦获得主节点信息，停止遍历（因此一般来说遍历到第一个哨兵节点，循环就停止了）。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">增加对哨兵的监听：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">这样当发生故障转移时，客户端便可以收到哨兵的通知，从而完成主节点的切换。具体做法是：利用Redis提供的发布订阅功能，为每一个哨兵节点开启一个单独的线程，订阅哨兵节点的+switch-master频道，当收到消息时，重新初始化连接池。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">3.总结</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">通过客户端原理的介绍，可以加深对哨兵功能的理解，如下：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置提供者：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">客户端可以通过哨兵节点+masterName获取主节点信息，在这里哨兵起到的作用就是配置提供者。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">需要注意的是，哨兵只是配置提供者，而不是代理。二者的区别在于：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><br  /></span></p><ul class=" list-paddingleft-2" style="list-style-type: disc;"><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">如果是配置提供者，客户端在通过哨兵获得主节点信息后，会直接建立到主节点的连接，后续的请求（如set/get）会直接发向主节点；</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">如果是代理，客户端的每一次请求都会发向哨兵，哨兵再通过主节点处理请求。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">举一个例子可以很好的理解哨兵的作用是配置提供者，而不是代理。在前面部署的哨兵系统中，将哨兵节点的配置文件进行如下修改：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="88286" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="135brush">
<p><span style="font-size: 10px;">sentinel monitor &nbsp; mymaster&nbsp;192.168.92.128&nbsp;6379&nbsp;2</span></p>
<p><span style="font-size: 10px;">改为</span></p>
<p><span style="font-size: 10px;">sentinel monitor mymaster&nbsp;127.0.0.1&nbsp;6379&nbsp;2</span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">然后，将前述客户端代码在局域网的另外一台机器上运行，会发现客户端无法连接主节点；这是因为哨兵作为配置提供者，客户端通过它查询到主节点的地址为127.0.0.1:6379，客户端会向127.0.0.1:6379建立Redis连接，自然无法连接。如果哨兵是代理，这个问题就不会出现了。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">通知：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点在故障转移完成后，会将新的主节点信息发送给客户端，以便客户端及时切换主节点。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
<p style="font-size: 20px;line-height: normal;letter-spacing: 0.5px;"><strong><span style="font-size: 16px;">四、基本原理</span></strong></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">前面介绍了哨兵部署、使用的基本方法，本部分介绍哨兵实现的基本原理。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">1.哨兵节点支持的命令</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点作为运行在特殊模式下的Redis节点，其支持的命令与普通的Redis节点不同。在运维中，我们可以通过这些命令查询或修改哨兵系统；不过更重要的是，哨兵系统要实现故障发现、故障转移等各种功能，离不开哨兵节点之间的通信，而通信的很大一部分是通过哨兵节点支持的命令来实现的。下面介绍哨兵节点支持的主要命令：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><span style="color: rgb(19, 139, 222);"><strong>基础查询：</strong></span></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;"><br  /></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">通过这些命令，可以查询哨兵系统的拓扑结构、节点信息、配置信息等。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">info sentinel：获取监控的所有主节点的基本信息。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel masters：获取监控的所有主节点的详细信息。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel master mymaster：获取监控的主节点mymaster的详细信息。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel slaves mymaster：获取监控的主节点mymaster的从节点的详细信息。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel sentinels mymaster：获取监控的主节点mymaster的哨兵节点的详细信息。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel get - master - addr - by- name mymaster：获取监控的主节点mymaster的地址信息，前文已有介绍。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel is-master-down-by-addr：哨兵节点之间可以通过该命令询问主节点是否下线，从而对是否客观下线做出判断。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;color: #138bde;">增加/移除对主节点的监控：</span></strong></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel monitor mymaster2 192.168.92.128 16379 2：与部署哨兵节点时配置文件中的sentinel monitor功能完全一样，不再详述。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel remove mymaster2：取消当前哨兵节点对主节点mymaster2的监控。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">强制故障转移：</span></strong></span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel failover mymaster：该命令可以强制对mymaster执行故障转移，即便当前的主节点运行完好；例如，如果当前主节点所在机器即将报废，便可以提前通过failover命令进行故障转移。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">2.基本原理</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">关于哨兵的原理，关键是了解以下几个概念：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">定时任务：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">每个哨兵节点维护了3个定时任务。定时任务的功能分别如下：通过向主从节点发送info命令获取最新的主从结构；通过发布订阅功能获取其他哨兵节点的信息；通过向其他节点发送ping命令进行心跳检测，判断是否下线。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">主观下线：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在心跳检测的定时任务中，如果其他节点超过一定时间没有回复，哨兵节点就会将其进行主观下线。顾名思义，主观下线的意思是一个哨兵节点“主观地”判断下线；与主观下线相对应的是客观下线。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">客观下线：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点在对主节点进行主观下线后，会通过sentinel is-master-down-by-addr命令询问其他哨兵节点该主节点的状态；如果判断主节点下线的哨兵数量达到一定数值，则对该主节点进行客观下线。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">需要特别注意的是，客观下线是主节点才有的概念；如果从节点和哨兵节点发生故障，被哨兵主观下线后，不会再有后续的客观下线和故障转移操作。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">选举领导者哨兵节点：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">当主节点被判断客观下线以后，各个哨兵节点会进行协商，选举出一个领导者哨兵节点，并由该领导者节点对其进行故障转移操作。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">监视该主节点的所有哨兵都有可能被选为领导者，选举使用的算法是Raft算法；Raft算法的基本思路是先到先得：即在一轮选举中，哨兵A向B发送成为领导者的申请，如果B没有同意过其他哨兵，则会同意A成为领导者。选举的具体过程这里不做详细描述，一般来说，哨兵选择的过程很快，谁先完成客观下线，一般就能成为领导者。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">故障转移：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">选举出的领导者哨兵，开始进行故障转移操作，该操作大体可以分为3个步骤：</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在从节点中选择新的主节点：选择的原则是，首先过滤掉不健康的从节点；然后选择优先级最高的从节点（由slave-priority指定）；如果优先级无法区分，则选择复制偏移量最大的从节点；如果仍无法区分，则选择runid最小的从节点。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">更新主从状态：通过slaveof no one命令，让选出来的从节点成为主节点；并通过slaveof命令让其他节点成为其从节点。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">将已经下线的主节点（即6379）设置为新的主节点的从节点，当6379重新上线后，它会成为新的主节点的从节点。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">通过上述几个关键概念，可以基本了解哨兵的工作原理。为了更形象的说明，下图展示了领导者哨兵节点的日志，包括从节点启动到完成故障转移。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="text-align: center;"><img class="" data-copyright="0" data-ratio="0.39797507788161995" data-s="300,640" src="/images/articles/20181020001_011.webp" data-type="png" data-w="1284" style=""></p>
<p style="text-align: center;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
<p style="font-size: 20px;line-height: normal;letter-spacing: 0.5px;"><span style="font-size: 16px;"><strong>五、配置与实践建议</strong></span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">1.配置</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">下面介绍与哨兵相关的几个配置。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置1：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel monitor {masterName} {masterIp} {masterPort} {quorum}</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel monitor是哨兵最核心的配置，在前文讲述部署哨兵节点时已说明，其中：masterName指定了主节点名称，masterIp和masterPort指定了主节点地址，quorum是判断主节点客观下线的哨兵数量阈值：当判定主节点下线的哨兵数量达到quorum时，对主节点进行客观下线。建议取值为哨兵数量的一半加1。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置2：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel down-after-milliseconds {masterName} {time}</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel down-after-milliseconds与主观下线的判断有关：哨兵使用ping命令对其他节点进行心跳检测，如果其他节点超过down-after-milliseconds配置的时间没有回复，哨兵就会将其进行主观下线。该配置对主节点、从节点和哨兵节点的主观下线判定都有效。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">down-after-milliseconds的默认值是30000，即30s；可以根据不同的网络环境和应用要求来调整：值越大，对主观下线的判定会越宽松，好处是误判的可能性小，坏处是故障发现和故障转移的时间变长，客户端等待的时间也会变长。例如，如果应用对可用性要求较高，则可以将值适当调小，当故障发生时尽快完成转移；如果网络环境相对较差，可以适当提高该阈值，避免频繁误判。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置3：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel parallel - syncs {masterName} {number}</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel parallel-syncs与故障转移之后从节点的复制有关：它规定了每次向新的主节点发起复制操作的从节点个数。例如，假设主节点切换完成之后，有3个从节点要向新的主节点发起复制；如果parallel-syncs=1，则从节点会一个一个开始复制；如果parallel-syncs=3，则3个从节点会一起开始复制。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">parallel-syncs取值越大，从节点完成复制的时间越快，但是对主节点的网络负载、硬盘负载造成的压力也越大；应根据实际情况设置。例如，如果主节点的负载较低，而从节点对服务可用的要求较高，可以适量增加parallel-syncs取值。parallel-syncs的默认值是1。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置4：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel failover - timeout {masterName} {time}</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">sentinel failover-timeout与故障转移超时的判断有关，但是该参数不是用来判断整个故障转移阶段的超时，而是其几个子阶段的超时，例如如果主节点晋升从节点时间超过timeout，或从节点向新的主节点发起复制操作的时间（不包括复制数据的时间）超过timeout，都会导致故障转移超时失败。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">failover-timeout的默认值是180000，即180s；如果超时，则下一次该值会变为原来的2倍。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="color: #138bde;"><strong><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">配置5：</span></strong></span><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">除上述几个参数外，还有一些其他参数，如安全验证相关的参数，这里不做介绍。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">2.实践建议</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">哨兵节点的数量应不止一个。一方面增加哨兵节点的冗余，避免哨兵本身成为高可用的瓶颈；另一方面减少对下线的误判。此外，这些不同的哨兵节点应部署在不同的物理机上。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">哨兵节点的数量应该是奇数，便于哨兵通过投票做出“决策”：领导者选举的决策、客观下线的决策等。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">各个哨兵节点的配置应一致，包括硬件、参数等；此外，所有节点都应该使用ntp或类似服务，保证时间准确、一致。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">哨兵的配置提供者和通知客户端功能，需要客户端的支持才能实现，如前文所说的Jedis；如果开发者使用的库未提供相应支持，则可能需要开发者自己实现。</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;caret-color: red;">当哨兵系统中的节点在Docker（或其他可能进行端口映射的软件）中部署时，应特别注意端口映射可能会导致哨兵系统无法正常工作，因为哨兵的工作基于与其他节点的通信，而Docker的端口映射可能导致哨兵无法连接到其他节点。例如，哨兵之间互相发现，依赖于它们对外宣称的IP和port，如果某个哨兵A部署在做了端口映射的Docker中，那么其他哨兵使用A宣称的port无法连接到A。</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="86122" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section style="margin-top: 0.5em;margin-bottom: 0.5em;"><section style="padding-bottom: 2px;text-align: center;color: rgb(255, 255, 255);background-color: rgb(19, 139, 222);box-sizing: border-box;"><section style="border-bottom: 1px solid rgb(254, 254, 254);border-top-color: rgb(19, 139, 222);border-right-color: rgb(19, 139, 222);border-left-color: rgb(19, 139, 222);padding: 0.5em 1.5em;box-sizing: border-box;">
<p style="font-size: 20px;letter-spacing: 0.5px;line-height: normal;"><span style="font-size: 16px;"><strong>六、总结</strong></span></p></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">本文首先介绍了哨兵的作用：监控、故障转移、配置提供者和通知；然后讲述了哨兵系统的部署方法，以及通过客户端访问哨兵系统的方法；再然后简要说明了哨兵实现的基本原理；最后给出了关于哨兵实践的一些建议。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">在主从复制的基础上，哨兵引入了主节点的自动故障转移，进一步提高了Redis的高可用性；但是哨兵的缺陷同样很明显：哨兵无法对从节点进行自动故障转移，在读写分离场景下，从节点故障会导致读服务不可用，需要我们对从节点做额外的监控、切换操作。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;font-size: 15px;">此外，哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题；这些问题的解决需要使用集群，欢迎关注社群后续内容。</span></p>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde"><section class="_135editor" data-tools="135编辑器" data-id="39" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;" data-color="#138bde" data-custom="#1e9be8"><section style="max-width: 100%;margin-top: 0.8em;margin-bottom: 0.5em;overflow: hidden;"><section class="135brush" data-brushtype="text" placeholder="请输入标题" style="height: 36px;display: inline-block;color: rgb(255, 255, 255);font-weight: bold;padding-right: 10px;padding-left: 10px;line-height: 36px;vertical-align: top;background-color: rgb(19, 139, 222);box-sizing: border-box !important;"><span style="font-size: 15px;">参考</span></section><section style="display: inline-block;height: 36px;vertical-align: top;border-left: 9px solid #138bde;box-sizing: border-box !important;border-top: 18px solid transparent !important;border-bottom: 18px solid transparent !important;"></section></section></section></section>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><br  /></p><ul class=" list-paddingleft-2" style=""><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;font-size: 14px;">https://redis.io/topics/sentinel</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;caret-color: red;font-size: 14px;">http://www.redis.cn/</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;caret-color: red;font-size: 14px;">《Redis开发与运维》</span></p></li><li>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: left;"><span style="font-family: 微软雅黑, sans-serif;caret-color: red;font-size: 14px;">《Redis设计与实现》</span></p></li></ul>
<p style="line-height: 1.75em;letter-spacing: 0.5px;margin-left: 5px;margin-right: 5px;text-align: justify;"><span style="font-family: 微软雅黑, sans-serif;caret-color: red;font-size: 14px;"><br  /></span></p><section class="" data-tools="135编辑器" data-id="88286" style="color: rgb(51, 51, 51);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 16px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;"><section style="margin-top: 10px;margin-bottom: 10px;"><section style="margin-top: -4px;padding: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"><section class="">
					
					
                </div>
                
                
                
                            </div>
                                    
                        

                      </div>
        </div>

        <div class="rich_media_area_primary sougou" id="sg_tj" style="display:none"></div>


        

    </div>
</div>

<div style="text-align:center;">
    &nbsp; &nbsp; &nbsp; &nbsp;  <a href="http://www.miibeian.gov.cn" target="_blank">京ICP备15003959号</a> &nbsp;   &nbsp; 
<script src='http://s22.cnzz.com/stat.php?id=3593514&web_id=3593514' language='JavaScript'></script> &nbsp;   &nbsp; 
<a href="https://mp.weixin.qq.com/s/rzIpWzgyiraC0ZOVe3YZDA" target="_blank">原文链接</a>
</div>
    </body>
    
</html>

